package fr.axones.pocketagile.services.remote
{
	import com.adobe.rtc.events.UserEvent;
	import com.adobe.rtc.sharedManagers.descriptors.UserDescriptor;
	
	import flash.events.EventDispatcher;
	
	import mx.collections.ArrayCollection;
	import mx.collections.ISort;
	import mx.events.FlexEvent;
	
	import spark.collections.Sort;
	import spark.collections.SortField;
	import spark.components.NavigatorContent;
	import spark.components.View;
	import spark.transitions.ViewTransitionBase;
	
	import fr.axones.pocketagile.ui.model.Model;
	import fr.axones.pocketagile.ui.view.main.planningpoker.PlanningPokerSelectValueView;
	import fr.axones.pocketagile.ui.view.main.planningpoker.PlanningPokerFinalValueView;
	import fr.axones.pocketagile.ui.view.main.planningpoker.PlanningPokerStartRoomView;
	import fr.axones.pocketagile.ui.view.authentication.AuthenticationView;
	import fr.axones.pocketagile.ui.view.main.project.item.ProjectItemSelectValueView;
	
	import fr.axones.pocketagile.vo.ConnectedUserVO;
	import fr.axones.pocketagile.vo.UserVO;

	public class ConnectedUsersService extends EventDispatcher
	{
		[Inject(id="model")]
		public var model:Model;
		
		private var registeredFieldCount:Number = 0;
		private var registeredFieldLenght:Number = 0;
		
		private var ac:ArrayCollection = new ArrayCollection();
		
		public function ConnectedUsersService()
		{
		}
		
		public function registerMe():void
		{
			model.session.userManager.addEventListener(UserEvent.CUSTOM_FIELD_REGISTER, customFieldRegisterHandler);
			
			registeredFieldCount = 0;
			registeredFieldLenght = 0;
			
			registerField("projectId");
			registerField("displayName");
			registerField("projectProfile");
			registerField("value");
			registerField("itemName");
			registerField("showValues");
			registerField("userId");
			
			if(registeredFieldCount == registeredFieldLenght)
			{
				registerMeComplete();
			}
		}
		
		private function registerMeComplete():void
		{
			assignField("projectId",model.project.id);
			assignField("displayName",model.user.displayName);
			assignField("projectProfile",model.projectProfile);
			assignField("value",-1);
			assignField("itemName","");
			assignField("showValues",false);
			assignField("userId",model.user.id);
		}
		
		public function assignField(fieldName:String, fieldValue:*):void
		{
			model.session.userManager.setCustomUserField(model.session.userManager.myUserID, fieldName, fieldValue);
		}
		
		public function addUserChangeListeners():void
		{
			model.session.userManager.addEventListener(UserEvent.USER_CREATE, userConnectedChangeHandler);
			model.session.userManager.addEventListener(UserEvent.USER_REMOVE, userConnectedChangeHandler);
			model.session.userManager.addEventListener(UserEvent.CUSTOM_FIELD_REGISTER, userConnectedChangeHandler);
			model.session.userManager.addEventListener(UserEvent.CUSTOM_FIELD_CHANGE, userConnectedChangeHandler);
			userConnectedChangeHandler();
		}
		
		public function removeUserChangeListeners():void
		{
			model.session.userManager.removeEventListener(UserEvent.USER_CREATE, userConnectedChangeHandler);
			model.session.userManager.removeEventListener(UserEvent.USER_REMOVE, userConnectedChangeHandler);
			model.session.userManager.removeEventListener(UserEvent.CUSTOM_FIELD_REGISTER, userConnectedChangeHandler);
			model.session.userManager.removeEventListener(UserEvent.CUSTOM_FIELD_CHANGE, userConnectedChangeHandler);
		}
		
		private function userConnectedChangeHandler(event:UserEvent=null):void
		{
			ac.removeAll();
			
			var adminPresent:Boolean = false;
			
			for each(var ud:UserDescriptor in model.session.userManager.userCollection)
			{				
				if(ud.customFields.hasOwnProperty("projectId") && ud.customFields.projectId == model.project.id)
				{
					var user:ConnectedUserVO = ConnectedUserVO.build(ud.customFields);
					
					if(!containUser(ac, user))
					{
						ac.addItem(user);
					}
					
					if(user.projectProfile == UserVO.PROFILE_ADMIN)
					{
						updateAdmin(user);
						adminPresent = true;
					}
				}				
			}
			
			model.users.removeAll();
			model.users.addAll(ac);
			model.users.sort = getSortFunction();
			model.users.refresh();
			
			if(!adminPresent)
			{
				toAdminLeave();
			}
			else
			{
				toAdminNotLeave();
			}
		}
		
		private function containUser(ac:ArrayCollection, user:ConnectedUserVO):Boolean
		{
			for each (var u:ConnectedUserVO in ac)
			{
				if(u.userId == user.userId)
				{
					return true;
				}
			}
			return false;
		}
		
		private function getSortFunction():ISort
		{
			var dataSortField:SortField = new SortField();
			dataSortField.name = "displayName";
			dataSortField.numeric = false;
			
			var dataSort:Sort = new Sort();
			dataSort.fields = [dataSortField];
			
			return dataSort;
		}
		
		private function updateAdmin(user:ConnectedUserVO):void
		{
			if(model.itemName != user.itemName && user.itemName != "" && user.itemName != "@@@final@@@" && user.itemName != null)
			{
				toChooseValue();
			}
			else if(user.itemName == "@@@final@@@")
			{
				toFinalView();
			}

			if(user.itemName != "@@@final@@@")
			{
				model.lastItemName = model.itemName;
				model.itemName = user.itemName;
			}
			model.showValues = user.showValues;
			model.adminValue = user.value;
		}
		
		private function toChooseValue():void
		{
			if(!model.isAdmin)
			{
				if(model.navigator.activeView == ProjectItemSelectValueView as View)
				{
					var viewTransition:ViewTransitionBase = new ViewTransitionBase();
					viewTransition.addEventListener(FlexEvent.TRANSITION_END, toChooseView);
					model.navigator.popView();
				}
				else
				{
					toChooseView();
				}
			}
		}
		
		private function toChooseView(event:FlexEvent=null):void
		{
			assignField("value",-1);
			model.selectedValue = {value:-1,final:false};
			model.navigator.replaceView(PlanningPokerSelectValueView);
		}
		
		private function toFinalView(event:FlexEvent=null):void
		{
			if(!model.isAdmin)
			{
				model.navigator.replaceView(PlanningPokerFinalValueView);
			}
		}
		
		private function toAdminLeave():void
		{
			try{
				(model.navigator.activeView as Object).disconnectedPanel.show();
			}catch(e:Error){
				
			}
		}
		
		private function toAdminNotLeave():void
		{
			try{
				if((model.navigator.activeView as Object).disconnectedPanel.visible == true)
				{
					model.navigator.replaceView(PlanningPokerStartRoomView);	
				}
				(model.navigator.activeView as Object).disconnectedPanel.hide();
			}catch(e:Error){
				
			}
		}
		
		private function convertUserDescription(ud:UserDescriptor):Object
		{
			var o:Object = new Object();
			
			if(ud.customFields.hasOwnProperty("projectId"))
			{
				o["projectId"] = ud.customFields.projectId;
			}
			else
			{
				o["projectId"] = -1;
			}
			
			if(ud.customFields.hasOwnProperty("displayName"))
			{
				o["displayName"] = ud.customFields.displayName;
			}
			else
			{
				o["displayName"] = "";
				o["projectId"] = -1;
			}
			
			return o;
		}
		
		private function registerField(fieldName:String):void
		{
			registeredFieldLenght++;
			for each(var fn:String in model.session.userManager.customFieldNames)
			{
				if(fn == fieldName)
				{
					registeredFieldCount++;
					return;
				}
			}
			model.session.userManager.registerCustomUserField(fieldName);
		}
		
		private function customFieldRegisterHandler(event:UserEvent):void
		{
			registeredFieldCount++;
			
			if(registeredFieldCount == registeredFieldLenght)
			{
				registerMeComplete();
			}
		}
	}
}